package middle.ground.db;

import java.util.List;
import java.util.Map;

/**
 * 数据库操作基本接口
 *
 * @param <T>
 * @author jrl
 * @author jrl
 * @date 2020-12-01
 */
public interface BaseDao<T> {

	/**
	 * 将对象保存到数据库中
	 *
	 * @param t VO
	 * @return PO
	 */
	T add(T t);

	/**
	 * 批量插入
	 *
	 * @param ts
	 */
	void batchAdd(List<T> ts);

	/**
	 * 批量插入
	 *
	 * @param ts
	 * @param batchSize 批量提交的数量
	 */
	void batchAdd(List<T> ts, int batchSize);

	/**
	 * 更新对象 如果对象的值为null，那么数据库中的值也会被更新为null
	 *
	 * @param t VO||PO
	 * @return
	 */
	int update(T t);

	/**
	 * 更新对象 只更新值不为null的字段
	 * 除了一些特定的场景，一般都不建议使用该方法，尤其是被更新对象是从前端提交过来的时候。
	 * 如果只更新某个字段，前端通过json方式提交这个字段的值，服务器将其解析为对应的实体，updateNotNull并不知道只更新该值，它会把所有非空字段更新掉。
	 * 所以updateNotNull会造成漏洞，请谨慎使用
	 *
	 * @param t
	 * @return
	 */
	int updateNotNull(T t);

	/**
	 * 新增或更新对象
	 *
	 * @param t
	 */
	void merge(T t);

	/**
	 * 根据id删除对象，该方法会执行物理删除，请根据业务考虑物理删除和逻辑删除
	 *
	 * @param id
	 */
	int delete(Integer id);

	/**
	 * 根据id加载对象
	 *
	 * @param id 对象id
	 * @return PO
	 */
	T load(Integer id);

	/**
	 * 根据SQL获得一个对象
	 *
	 * @param sql
	 * @return PO
	 */
	T get(String sql);

	/**
	 * 根据SQL获得一个对象
	 *
	 * @param sql
	 * @param params 基于?占位符的参数列表
	 * @return PO
	 */
	T get(String sql, Object... params);

	/**
	 * 根据Class 及 SQL获得一个对象
	 *
	 * @param clazz
	 * @param sql
	 * @return Object
	 */
	default <C> C getEntity(Class<C> clazz, String sql) {
		return null;
	}

	;

	/**
	 * 根据Class 及 SQL获得一个对象
	 *
	 * @param clazz
	 * @param sql
	 * @param params 基于?占位符的参数列表
	 * @return PO
	 */
	default <C> C getEntity(Class<C> clazz, String sql, Object... params) {
		return null;
	}

	;

	/**
	 * 根据Class 及 SQL获得一个对象
	 *
	 * @param clazz
	 * @param sql
	 * @param alias 基于别名的参数集合
	 * @return PO
	 */
	default <C> C getEntity(Class<C> clazz, String sql, Map<String, Object> alias) {
		return null;
	}

	;

	/**
	 * 根据SQL获得一个对象
	 *
	 * @param sql
	 * @param alias 基于别名的参数集合
	 * @return PO
	 */
	T get(String sql, Map<String, Object> alias);

	/**
	 * 根据SQL更新对象
	 *
	 * @param sql
	 */
	int update(String sql);

	/**
	 * 根据SQL更新对象
	 *
	 * @param sql
	 * @param params 基于?占位符的参数列表
	 */
	int update(String sql, Object... params);

	/**
	 * 根据SQL更新对象
	 *
	 * @param sql
	 * @param alias 基于别名的参数集合
	 */
	int update(String sql, Map<String, Object> alias);

	/**
	 * 根据SQL查询对象列表
	 *
	 * @param sql
	 * @return PO列表
	 */
	List<T> list(String sql);

	/**
	 * 根据SQL获取对象列表 查询参数基于?占位符
	 *
	 * @param sql
	 * @param params 基于?占位符的参数列表
	 * @return PO列表
	 */
	List<T> list(String sql, Object... params);

	/**
	 * TODO
	 *
	 * @param clazz:
	 * @param sql:
	 * @return java.util.List<C>
	 */
	default <C> List<C> listEntity(Class<C> clazz, String sql) {
		return null;
	}

	;

	/**
	 * 根据SQL获取对象列表 查询参数基于别名
	 *
	 * @param sql
	 * @param alias 基于别名的参数集合
	 * @return PO列表
	 */
	List<T> list(String sql, Map<String, Object> alias);

	/**
	 * TODO
	 *
	 * @param
	 * @return java.util.List<C>
	 */
	default <C> List<C> listEntity(Class<C> clazz, String sql, Object... params) {
		return null;
	}

	;

	/**
	 * TODO
	 *
	 * @param clazz:
	 * @param sql:
	 * @param alias:
	 * @return java.util.List<C>
	 */
	default <C> List<C> listEntity(Class<C> clazz, String sql, Map<String, Object> alias) {
		return null;
	}

	;

	/**
	 * 根据SQL查询分页对象列表
	 *
	 * @param sql
	 * @param page
	 * @param limit
	 * @param params
	 * @return
	 */
	default Pagination<T> page(String sql, int page, int limit, Object... params) {
		return null;
	}

	;

	/**
	 * TODO
	 *
	 * @param clazz:
	 * @param sql:
	 * @param page:
	 * @param limit:
	 * @param params:
	 * @return middle.ground.dao.Pagination<C>
	 */
	default <C> Pagination<C> pageEntity(Class<C> clazz, String sql, int page, int limit, Object... params) {
		return null;
	}

	;

	/**
	 * 查询总数
	 *
	 * @return
	 */
	Integer count();

	/**
	 * 查询总数
	 *
	 * @param sql
	 * @param params
	 * @return
	 */
	Integer count(String sql, Object... params);

	/**
	 * 计算汇总
	 *
	 * @param sql
	 * @param params
	 * @return
	 */
	Long sum(String sql, Object... params);

	default boolean existTable(String tableName) {
		return false;
	}

}
